package top.yaofengqiao.springcloudsimple.auth.biz.domain.auth.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.yaofengqiao.springcloudsimple.auth.biz.config.AliPayConfigProperties;
import top.yaofengqiao.springcloudsimple.auth.biz.domain.auth.model.entity.UserOauth2Entity;
import top.yaofengqiao.springcloudsimple.auth.biz.domain.auth.service.AbstractOauth2Service;
import top.yaofengqiao.springcloudsimple.common.constant.ResponseCode;
import top.yaofengqiao.springcloudsimple.common.util.AppException;

import javax.annotation.Resource;

/**
 * @author yfq
 * @date 2024/6/11 13:48
 * @description 支付宝授权服务
 */
@Slf4j
@Service
public class AliPayOauth2Service extends AbstractOauth2Service {
    @Resource
    private AliPayConfigProperties properties;

    /**
     * 使用code换取accessToken
     */
    @Override
    protected String getAccessToken(String code) {
        AlipayClient aliPayClient = createAliPayClient();
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode(code);
        request.setGrantType("authorization_code");
        try {
            AlipaySystemOauthTokenResponse oauthTokenResponse = aliPayClient.execute(request);
            return oauthTokenResponse.getAccessToken();
        } catch (Exception e) {
            log.error("授权码换取accessToken异常：code:{}", code, e);
        }

        throw new AppException(ResponseCode.ALIPAY_LOGIN_FAIL);
    }

    /**
     * 获取支付宝用户信息
     */
    @Override
    protected UserOauth2Entity getUserInfo(String accessToken) {
        AlipayClient aliPayClient = createAliPayClient();
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        try {
            AlipayUserInfoShareResponse response = aliPayClient.execute(request, accessToken);
            if (response.isSuccess()) return buildUserOauth2Entity(response);
        } catch (Exception e) {
            log.error("创建获取支付宝用户信息异常：accessToken:{}", accessToken, e);
        }

        throw new AppException(ResponseCode.ALIPAY_LOGIN_FAIL);
    }

    @Override
    public String getOauth2Url() {
        String appid = properties.getAppid();
        String redirectUrl = properties.getRedirectUrl();
        String temp = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=%s&scope=auth_user&redirect_uri=%s&state=init";

        return String.format(temp, appid, redirectUrl);
    }

    private AlipayClient createAliPayClient() {
        try {
            AlipayConfig alipayConfig = new AlipayConfig();
            alipayConfig.setServerUrl(properties.getUrl());
            alipayConfig.setAppId(properties.getAppid());
            alipayConfig.setPrivateKey(properties.getPrivateKey());
            alipayConfig.setFormat("json");
            alipayConfig.setCharset("UTF-8");
            alipayConfig.setAlipayPublicKey(properties.getAlipayPublicKey());
            alipayConfig.setSignType("RSA2");
            return new DefaultAlipayClient(alipayConfig);
        } catch (Exception e) {
            log.error("创建AlipayClient异常：", e);
            throw new AppException(ResponseCode.ALIPAY_LOGIN_FAIL);
        }
    }

    private UserOauth2Entity buildUserOauth2Entity(AlipayUserInfoShareResponse response) {
        return UserOauth2Entity.builder()
                .mobile(response.getMobile())
                .avatar(response.getAvatar())
                .name(response.getUserName())
                .nickname(response.getNickName())
                .openid(response.getOpenId())
                .build();
    }
}
